package com.ttbj.exception.resolver;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutionException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.ttbj.exception.WebException;
import com.ttbj.product.bean.dto.ViewData;
import com.ttbj.product.bean.exception.BusinessException;
import com.ttbj.util.JsonTools;

/**
 * 
 * <p>
 * Title: ExceptionResolverCustom
 * </p>
 * <p>
 * Description:全局异常处理器
 * </p>
 * <p>
 * Company: zywl
 * 
 * @author Medivh
 *         </p>
 * 
 */
public class ExceptionResolveCutom implements HandlerExceptionResolver {

	public static final Logger log = LoggerFactory.getLogger(ExceptionResolveCutom.class);
	// json转换器
	// 将异常信息转json
	private HttpMessageConverter<WebException> jsonMessageConverter;

	// 前端控制器调用此方法执行异常处理
	// handler，执行的action类就包装了一个方法（对应url的方法）
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		// 输出 异常信息
		ex.printStackTrace();
		// 转成springmvc底层对象（就是对action方法的封装对象，只有一个方法）
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		// 取出方法
		Method method = handlerMethod.getMethod();
		// 判断方法是否返回json
		// 只要方法上有responsebody注解表示返回json
		// 查询method是否有responsebody注解
		ResponseBody responseBody = AnnotationUtils.findAnnotation(method, ResponseBody.class);
		if (responseBody != null) {
			// 将异常信息转json输出
			return this.resolveJsonException(request, response, handlerMethod, ex);
		}
		// 这里说明action返回的是jsp页面
		// 解析异常
		WebException exceptionResultInfo = resolveExceptionCustom(ex);
		String view = "/base/error";
		// 异常代码
		/*
		 * int messageCode = exceptionResultInfo.getModel().getErrorcode()
		 * //如果是106则跳转到登陆 if(messageCode==106){ //跳转到登陆 view = "/base/login"; }
		 */
		// 将异常信息在异常页面显示
		request.setAttribute("exceptionResultInfo", exceptionResultInfo.getModel());
		// 转向错误页面
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("exceptionResultInfo", exceptionResultInfo.getModel());
		modelAndView.setViewName(view);// 逻辑视图名
		return modelAndView;
	}

	// 异常信息解析方法
	private WebException resolveExceptionCustom(Exception ex) {
		ViewData resultInfo = null;
		if (ex instanceof WebException) {
			// 抛出的是系统自定义异常
			resultInfo = ((WebException) ex).getModel();
		} else if (ex instanceof BusinessException) {
			resultInfo = new ViewData();
			resultInfo.setStatus(99999);
			resultInfo.setMessage("未知错误！");
			String message = ((BusinessException) ex).getMessage();
			Integer code = ((BusinessException) ex).getErrorCode();
			if (!message.isEmpty()) {
				resultInfo.setMessage(message);
			}
			if (code != null) {
				resultInfo.setStatus(code);
			}
		} else if (ex instanceof InterruptedException || ex instanceof ExecutionException) {
			resultInfo = new ViewData();
			resultInfo.setStatus(99999);
			String message = ex.getMessage();
			if(message.contains(":")){
				message = message.split(":")[1];
			}else{
				message = "未知错误";
			}
			resultInfo.setMessage(message);
			
		} else {
			// 重新构造“未知错误”异常
			resultInfo = new ViewData();
			resultInfo.setStatus(99999);
			resultInfo.setMessage("未知错误！");
		}

		return new WebException(resultInfo);
	}

	// 将异常信息转json输出
	private ModelAndView resolveJsonException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		// 解析异常
		WebException webException = resolveExceptionCustom(ex);
		response.setContentType("application/json;charset=utf-8");
		try {
			response.getOutputStream().write(JsonTools.GsonString(webException.getModel()).getBytes("UTF-8"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new ModelAndView();

	}

	public HttpMessageConverter<WebException> getJsonMessageConverter() {
		return jsonMessageConverter;
	}

	public void setJsonMessageConverter(HttpMessageConverter<WebException> jsonMessageConverter) {
		this.jsonMessageConverter = jsonMessageConverter;
	}

}
